home *** CD-ROM | disk | FTP | other *** search
/ Aminet 31 / Aminet 31 (1999)(Schatztruhe)[!][Jun 1999].iso / Aminet / disk / cdrom / JoyControl32.lha / joycontrol32 / JoyControl32.e < prev    next >
Encoding:
Text File  |  1999-03-08  |  13.2 KB  |  457 lines

  1. -> JoyControl32
  2.  
  3. ->>> Header (globals)
  4. MODULE 'amigalib/ports',
  5.        'amigalib/io',
  6.        'devices/gameport',
  7.        'devices/inputevent',
  8.        'devices/timer',
  9.        'exec/execbase',
  10.        'exec/io',
  11.        'exec/nodes',
  12.        'exec/ports',
  13.     'workbench/workbench',
  14.     'icon',
  15.     'wb',
  16.     'intuition/intuition',
  17.     'workbench/startup' 
  18.  
  19.  
  20.  
  21. ENUM ERR_NONE, ERR_DEV, ERR_IO, ERR_PORT,NOICONLIB,NOWBLIB, ERR_APPICON, ERR_DOBJ, ERR_LIB
  22.  
  23.  
  24. RAISE ERR_DEV IF OpenDevice()<>0,
  25.       ERR_APPICON IF AddAppIconA()=NIL,
  26.       ERR_DOBJ    IF GetDefDiskObject()=NIL,
  27.       ERR_LIB     IF OpenLibrary()=NIL,
  28.       ERR_PORT    IF CreateMsgPort()=NIL
  29.  
  30. CONST JOY_X_DELTA=1, JOY_Y_DELTA=1
  31.  
  32. DEF exec:PTR TO execbase,  cdresult, oldcdresult, rg:PTR TO wbarg, myargs:PTR TO LONG, wbm:PTR TO wbstartup,dir,
  33.     pname,z[200]:STRING,string[200]:STRING, do:PTR TO diskobject, doapp:PTR TO diskobject,
  34.     tenth_off_second,check_every, myport=NIL, appicon=NIL, appmsg:PTR TO appmessage, dropcount
  35.  
  36. -> Allocate everything and go.  On failure, free any resources that have been allocated.
  37. PROC main() HANDLE
  38.   DEF joytrigger:gameporttrigger, game_io_msg=NIL:PTR TO iostd,
  39.       game_msg_port=NIL, open_dev=FALSE
  40.  
  41.    VOID '$VER: Joy32 1.0 (9.2.99) sorenf@hem1.passagen.se'
  42.     -> open the resources we need...
  43.    workbenchbase:=OpenLibrary('workbench.library',37)
  44.     IF (workbenchbase:=OpenLibrary('workbench.library',
  45.     37))=NIL THEN Raise(NOWBLIB)
  46.  
  47.  
  48.  
  49.     IF (iconbase:=OpenLibrary('icon.library',37))=NIL THEN Raise(NOICONLIB)
  50.     myargs:=[0,0,0,0,0,0,0,0,0,0,0] -> static array for the arg's
  51.     wbm:=wbmessage
  52.     tenth_off_second:=exec.vblankfrequency/10
  53.     -> compute program's path and name, i.e. get it from the wbmessage
  54.     IF wbmessage
  55.         IF wbm.numargs>0
  56.             rg:=wbm.arglist+((wbm.numargs-1)*SIZEOF wbarg)
  57.             dir:=CurrentDir(rg[].lock)
  58.             pname:=rg.name
  59.         ELSE
  60.             pname:='progdir:joycon32'
  61.         ENDIF
  62.     ELSE
  63.         pname:=StringF(string,'progdir:\s',GetProgramName(z,200) BUT z)
  64.     ENDIF
  65.     -> we must have an icon!
  66.     IF do:=GetDiskObject(pname)
  67.         myargs[0]:=FindToolType(do.tooltypes,'PLAY')
  68.         myargs[1]:=FindToolType(do.tooltypes,'FFW')
  69.         myargs[2]:=FindToolType(do.tooltypes,'RWD')
  70.         myargs[3]:=FindToolType(do.tooltypes,'CD32_G')
  71.         myargs[4]:=FindToolType(do.tooltypes,'CD32_Y')
  72.         myargs[5]:=FindToolType(do.tooltypes,'FIRE1')
  73.         myargs[6]:=FindToolType(do.tooltypes,'FIRE2')
  74.         myargs[7]:=FindToolType(do.tooltypes,'UP')
  75.         myargs[8]:=FindToolType(do.tooltypes,'DOWN')
  76.         myargs[9]:=FindToolType(do.tooltypes,'LEFT')
  77.         myargs[10]:=FindToolType(do.tooltypes,'RIGHT')
  78.         myargs[11]:=FindToolType(do.tooltypes,'CHECK_EVERY')
  79.  
  80.         IF myargs[11] THEN check_every:=Val(myargs[11]) ELSE check_every:=1
  81.     ELSE
  82.         Raise(NIL)
  83.     ENDIF
  84.  
  85.   -> This is a easy way to get some icon imagery altough not so elegant
  86.  
  87.   -> E-Note: get the right type for exec
  88.   exec:=execbase
  89.   -> Create port for gameport device communications
  90.   IF NIL=(game_msg_port:=createPort('RKM_game_port', 0))
  91.     Raise(ERR_PORT)
  92.   ENDIF
  93.   -> Create message block for device IO
  94.   IF NIL=(game_io_msg:=createExtIO(game_msg_port, SIZEOF iostd))
  95.     Raise(ERR_IO)
  96.   ENDIF
  97.  
  98.   game_io_msg.mn.ln.type:=NT_UNKNOWN
  99.   -> Open the right/back (unit 1, number 2) gameport.device unit
  100.   OpenDevice('gameport.device', 1, game_io_msg, 0)
  101.   open_dev:=TRUE
  102.   -> Set controller type to joystick
  103.   IF set_controller_type(GPCT_ABSJOYSTICK, game_io_msg)
  104.     -> Specify the trigger conditions
  105.     set_trigger_conditions(joytrigger, game_io_msg)
  106.  
  107. ->  WriteF('\n >>> JoyControl32 <<<\n\n')
  108. makeapp()
  109.    
  110.     -> Clear device buffer to start from a known state.
  111.     -> There might still be events left.
  112.     flush_buffer(game_io_msg)
  113.  
  114.     processEvents(game_io_msg, game_msg_port) -> MainLOOP
  115.  
  116.     -> Free gameport unit so other applications can use it!
  117.     free_gp_unit(game_io_msg)
  118.   ENDIF
  119. EXCEPT DO
  120.   IF appicon THEN RemoveAppIcon(appicon)
  121.   IF myport
  122.     -> Clear away any messages that arrived at the last moment
  123.     WHILE appmsg:=GetMsg(myport) DO ReplyMsg(appmsg)
  124.     DeleteMsgPort(myport)
  125.   ENDIF
  126.   IF do THEN FreeDiskObject(do)
  127.   IF workbenchbase THEN CloseLibrary(workbenchbase)
  128.   IF iconbase THEN CloseLibrary(iconbase)
  129.   IF open_dev THEN CloseDevice(game_io_msg)
  130.   IF game_io_msg THEN deleteExtIO(game_io_msg)
  131.   IF game_msg_port THEN deletePort(game_msg_port)
  132.   SELECT exception
  133.   CASE ERR_DEV;   WriteF('Error: could not open gameport device\n')
  134.   CASE ERR_IO;    WriteF('Error: could not create I/O\n')
  135.   CASE ERR_APPICON; WriteF('Error: Could not attach AppIcon to Workbench\n')
  136.   CASE ERR_DOBJ;    WriteF('Error: Could not get default icon\n')
  137.   CASE ERR_LIB;     WriteF('Error: Could not open required library\n')
  138.   CASE ERR_PORT;    WriteF('Error: Could not create port\n')
  139.   ENDSELECT
  140. ENDPROC
  141.  
  142.  
  143. ->>> PROC check_move(game_event:PTR TO inputevent)
  144. -> Print out information on the event received.
  145. PROC check_move(game_event:PTR TO inputevent)
  146.   DEF xmove, ymove, timeout=FALSE
  147.   xmove:=game_event.x
  148.   ymove:=game_event.y
  149.  
  150.   IF xmove=1
  151.     IF ymove=1
  152.       WriteF('RIGHT DOWN\n')
  153.     ELSEIF ymove=0
  154.       WriteF('RIGHT\n')
  155.         action(10)
  156.     ELSEIF ymove=-1
  157.       WriteF('RIGHT UP\n')
  158.  
  159.     ELSE
  160.       WriteF('UNKNOWN Y\n')
  161.     ENDIF
  162.   ELSEIF xmove=-1
  163.     IF ymove=1
  164.       WriteF('LEFT DOWN\n')
  165.     ELSEIF ymove=0
  166.       WriteF('LEFT\n')
  167.         action(9)
  168.     ELSEIF ymove=-1
  169.       WriteF('LEFT UP\n')
  170.     ELSE
  171.       WriteF('UNKNOWN Y\n')
  172.     ENDIF
  173.   ELSEIF xmove=0
  174.     IF ymove=1
  175.       WriteF('DOWN\n')
  176.         action(8)
  177.     ELSEIF ymove=0
  178.       -> Note that 0,0 can be a timeout, or a direction release.
  179.       IF game_event.timestamp.secs >= (tenth_off_second*check_every)
  180.         -> Under 1.3 (V34) and earlier versions of the Amiga OS, the
  181.         -> timestamp.secs field used in the IF statement above is not
  182.         -> correctly filled in.  Therefore, this program cannot tell the
  183.         -> difference between a release event and a timeout under 1.3 (release
  184.         -> events will be reported as timeouts).
  185.  ->       WriteF('TIMEOUT\n')
  186.         timeout:=TRUE
  187.     ELSE
  188. WriteF('release\n')
  189.       ENDIF
  190.     ELSEIF ymove=-1
  191.       WriteF('UP\n')
  192.         action(7)
  193.     ELSE
  194.       WriteF('UNKNOWN Y\n')
  195.     ENDIF
  196.   ELSE
  197.     WriteF('UNKNOWN X ')
  198.     IF ymove=1
  199.       WriteF('unknown action\n')
  200.     ELSEIF ymove=0
  201.       WriteF('unknown action\n')
  202.     ELSEIF ymove=-1
  203.       WriteF('unknown action\n')
  204.     ELSE
  205.       WriteF('UNKNOWN Y\n')
  206.     ENDIF
  207.   ENDIF
  208.  
  209. checkcd32()
  210. actioncd32()
  211.  
  212. ENDPROC timeout
  213. ->>>
  214.  
  215. ->>> PROC send_read_request(game_event, game_io_msg:PTR TO iostd)
  216. -> Send a request to the gameport to read an event.
  217. PROC send_read_request(game_event, game_io_msg:PTR TO iostd)
  218.   game_io_msg.command:=GPD_READEVENT
  219.   game_io_msg.flags:=0
  220.   game_io_msg.data:=game_event
  221.   game_io_msg.length:=SIZEOF inputevent
  222.   SendIO(game_io_msg)  -> Asynchronous - message will return later
  223. ENDPROC
  224. ->>>
  225.  
  226. ->>> PROC processEvents(game_io_msg:PTR TO iostd, game_msg_port:PTR TO mp)
  227. -> Simple loop to process gameport events.
  228. PROC processEvents(game_io_msg:PTR TO iostd, game_msg_port:PTR TO mp)
  229.   DEF timeout, timeouts, button_count, not_finished, code,
  230.       game_event:inputevent  -> Where input event will be stored
  231.   -> From now on, just read input events into the event buffer,
  232.   -> one at a time.  READEVENT waits for the preset conditions.
  233.   timeouts:=0
  234.   button_count:=0
  235.   not_finished:=TRUE
  236.  
  237.   WHILE  not_finished
  238.  
  239.     -> Send the read request
  240.     send_read_request(game_event, game_io_msg)
  241.     -> Wait for joystick action
  242.     Wait(Shl(1, game_msg_port.sigbit))
  243.     WHILE NIL<>GetMsg(game_msg_port)
  244.       timeout:=FALSE
  245.       code:=game_event.code
  246.       SELECT code
  247.       CASE IECODE_LBUTTON
  248.     ->    action(5)
  249.      ->   WriteF(' FIRE BUTTON PRESSED \n')
  250.       CASE IECODE_LBUTTON OR IECODE_UP_PREFIX
  251.         button_count++
  252.      ->   IF 3=button_count THEN not_finished:=FALSE
  253.       CASE IECODE_RBUTTON
  254.     ->    action(6)
  255.        -> WriteF(' ALT BUTTON PRESSED \n')
  256.         button_count:=0
  257.       CASE IECODE_RBUTTON OR IECODE_UP_PREFIX
  258.         button_count:=0
  259.       CASE IECODE_NOBUTTON
  260.  
  261.         -> Check for change in position
  262.         timeout:=check_move(game_event)
  263.         button_count:=0
  264.       DEFAULT
  265.       ENDSELECT
  266.  
  267.       IF timeout
  268.         INC timeouts
  269.       ELSE
  270.         timeouts:=0
  271.       ENDIF
  272. checkapp()
  273.     ENDWHILE
  274.   ENDWHILE
  275. ENDPROC
  276. ->>>
  277.  
  278. ->>> PROC set_controller_type(type, game_io_msg:PTR TO iostd)
  279. -> Allocate the controller if it is available.  You allocate the controller by
  280. -> setting its type to something other than GPCT_NOCONTROLLER.  Before you
  281. -> allocate the thing you need to check if anyone else is using it (it is free
  282. -> if it is set to GPCT_NOCONTROLLER).
  283. PROC set_controller_type(type, game_io_msg:PTR TO iostd)
  284.   DEF success=FALSE, controller_type_addr
  285.   controller_type_addr:=[0]:CHAR
  286.   -> Begin critical section.
  287.   -> We need to be sure that between the time we check that the controller is
  288.   -> available and the time we allocate it, no one else steals it.
  289.   Forbid()
  290.  
  291.   game_io_msg.command:=GPD_ASKCTYPE  -> Enquire current status
  292.   game_io_msg.flags:=IOF_QUICK
  293.   game_io_msg.data:=controller_type_addr  -> Put answer in here
  294.   game_io_msg.length:=1
  295.   DoIO(game_io_msg)
  296.  
  297.   -> No one is using this device unit, let's claim it
  298.   IF controller_type_addr[]=GPCT_NOCONTROLLER
  299.     game_io_msg.command:=GPD_SETCTYPE
  300.     game_io_msg.flags:=IOF_QUICK
  301.     game_io_msg.data:=[type]:CHAR
  302.     game_io_msg.length:=1
  303.     DoIO( game_io_msg)
  304.     success:=TRUE
  305.   ENDIF
  306.  
  307.   Permit()  -> Critical section end
  308. ENDPROC success
  309. ->>>
  310.  
  311. ->>> PROC set_trigger_conditions(gpt:PTR TO gameporttrigger, game_io_msg:...)
  312. -> Tell the gameport when to trigger.
  313. PROC set_trigger_conditions(gpt:PTR TO gameporttrigger,
  314.                             game_io_msg:PTR TO iostd)
  315.   -> Trigger on all joystick key transitions
  316.   gpt.keys:=GPTF_UPKEYS OR GPTF_DOWNKEYS
  317.   gpt.xdelta:=JOY_X_DELTA
  318.   gpt.ydelta:=JOY_Y_DELTA
  319.   -> Timeout trigger every check_every tenth off second
  320.  -> gpt.timeout:=tenth_off_second*check_every
  321.   gpt.timeout:=tenth_off_second*check_every
  322.   game_io_msg.command:=GPD_SETTRIGGER
  323.   game_io_msg.flags:=IOF_QUICK
  324.   game_io_msg.data:=gpt
  325.   game_io_msg.length:=SIZEOF gameporttrigger
  326.   DoIO(game_io_msg)
  327. ENDPROC
  328. ->>>
  329.  
  330. ->>> PROC flush_buffer(game_io_msg:PTR TO iostd)
  331. -> Clear the buffer.  Do this before you begin to be sure you start in a known
  332. -> state.
  333. PROC flush_buffer(game_io_msg:PTR TO iostd)
  334.   game_io_msg.command:=CMD_CLEAR
  335.   game_io_msg.flags:=IOF_QUICK
  336.   game_io_msg.data:=NIL
  337.   game_io_msg.length:=0
  338.   DoIO(game_io_msg)
  339. ENDPROC
  340. ->>>
  341.  
  342. ->>> PROC free_gp_unit(game_io_msg:PTR TO iostd)
  343. -> Free the unit by setting its type back to GPCT_NOCONTROLLER.
  344. PROC free_gp_unit(game_io_msg:PTR TO iostd)
  345.   DEF type=GPCT_NOCONTROLLER
  346.   game_io_msg.command:=GPD_SETCTYPE
  347.   game_io_msg.flags:=IOF_QUICK
  348.   game_io_msg.data:=[type]:CHAR
  349.   game_io_msg.length:=1;
  350.   DoIO(game_io_msg)
  351. ENDPROC
  352. ->>>
  353.  
  354.  
  355.  
  356. ->>>
  357. ->CD_PLAY    EQU 1
  358. ->CD_RWD    EQU 2
  359. ->CD_FFW    EQU 3
  360. ->CD_G    EQU 4
  361. ->CD_Y    EQU 5
  362. ->CD_R    EQU 6
  363. ->CD_B    EQU 7
  364.  
  365.  
  366. ->;***********************************************************************
  367. ->;Reads CD 32 Controller
  368. ->;You must read joystick positions or button in normal way
  369. ->;BEFORE you call this.
  370. ->;One VBL MUST have elapsed before repeating this!
  371. PROC checkcd32()
  372. Forbid()
  373. ->ReadCD32:
  374.         MOVEM.L    D0-D2,-(A7)        ->???
  375.         MOVEM.L    A0,-(A7)            ->???
  376.         BSET    #7,$bfe201
  377.         BCLR    #7,$bfe001
  378.         MOVE.W    #$6f00,$dff034
  379.         MOVEQ.L    #0,D0
  380.         MOVEQ.L    #7,D1
  381.         BRA.B    gamecont4    
  382.     
  383. gamecont3:
  384.         TST.B    $bfe001
  385.         TST.B    $bfe001
  386.         TST.B    $bfe001
  387.  
  388. gamecont4:
  389.         TST.B    $bfe001
  390.         TST.B    $bfe001
  391.         TST.B    $bfe001
  392.         TST.B    $bfe001
  393.         TST.B    $bfe001
  394.         MOVE.W    $dff016,D2
  395.         BSET    #7,$bfe001
  396.         BCLR    #7,$bfe001
  397.         BTST    #14,D2
  398.         BNE.B    gamecont5
  399.         BSET    D1,D0
  400.  
  401. gamecont5:
  402.         DBF    D1,gamecont3
  403.         
  404.         BCLR    #7,$bfe201
  405.         MOVE.W    #$ffff,$dff034
  406.         LEA    cdresult,A0            ->???
  407.         MOVE.B    D0,(A0)
  408.         MOVEM.L    (A7)+,A0            ->???
  409.         MOVEM.L    (A7)+,D0-D2        ->???
  410. Permit()
  411. ENDPROC
  412.  
  413. PROC actioncd32()
  414.     IF oldcdresult=0
  415.         IF cdresult = 33554432       THEN action(0) -> CD_PLAY
  416.         IF cdresult = 134217728   THEN action(1) -> CD_FFW
  417.         IF cdresult = 67108864       THEN action(2) -> CD_RWD
  418.         IF cdresult = 268435456   THEN action(3) -> CD_G
  419.         IF cdresult = 536870912   THEN action(4) -> CD_Y
  420.         IF cdresult = 1073741824  THEN action(5) -> CD_R  *** Same as FIRE1, we use that instead.
  421.         IF cdresult = -2147483648 THEN action(6) -> CD_B  *** Same as FIRE2, we use that instead.
  422.     ENDIF
  423.     oldcdresult:=cdresult
  424. ENDPROC
  425.  
  426. PROC action(button)
  427.     IF myargs[button] THEN Execute (myargs[button],0,NIL)
  428. ENDPROC
  429.  
  430.  
  431. PROC checkapp()
  432.     -> Might be more than one message at the port...
  433.     WHILE appmsg:=GetMsg(myport)
  434.      INC dropcount
  435.       IF appmsg.numargs=0
  436.         -> If numargs is 0 the AppIcon was activated directly
  437.        Raise(NIL)
  438.       ENDIF
  439.       -> Let Workbench know we're done with the message
  440.       ReplyMsg(appmsg)
  441.     ENDWHILE
  442. ENDPROC
  443.  
  444.  
  445. PROC makeapp()
  446. Execute ('rename  env:sys/def_disk.info env:sys/org_def_disk.info ',0,NIL)
  447. Execute ('copy JCapp.info env:sys/def_disk.info',0,NIL)
  448.   doapp:=GetDefDiskObject(WBDISK) ->ENV:sys/def_disk.info
  449.   -> The type must be set to NIL for a WBAPPICON
  450.   doapp.type:=NIL
  451.   -> The CreateMsgPort() function is in Exec version 37 and later only
  452.   myport:=CreateMsgPort()
  453.   -> Put the AppIcon up on the Workbench window
  454.   appicon:=AddAppIconA(0, 0, 'JoyControl32', myport, NIL, doapp, NIL)
  455. Execute ('delete env:sys/def_disk.info',0,NIL)
  456. Execute ('rename  env:sys/org_def_disk.info env:sys/def_disk.info ',0,NIL)
  457. ENDPROC